package com.fhs.trans.service.impl;

import com.fhs.cache.service.RedisCacheService;
import com.fhs.common.constant.Constant;
import com.fhs.common.utils.StringUtil;
import com.fhs.core.trans.anno.Trans;
import com.fhs.core.trans.config.TransConfig;
import com.fhs.core.trans.constant.TransType;
import com.fhs.core.trans.util.ReflectUtils;
import com.fhs.core.trans.vo.VO;
import com.fhs.trans.listener.TransMessageListener;
import com.fhs.trans.service.DictionaryTransCustomizer;
import com.fhs.trans.service.TransRegister;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 字典翻译服务
 *
 * @author jackwong
 * @date 2020-05-18 14:41:20
 */
public class DictionaryTransService implements ITransTypeService, TransRegister, InitializingBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(DictionaryTransService.class);

    /**
     * 用来放字典缓存的map
     */
    private Map<String, String> dictionaryTransMap = new ConcurrentHashMap<>();

    private Map<String, DictionaryTransCustomizer> dictionaryTransCustomizerMap = new ConcurrentHashMap<>();

    /**
     * redis缓存
     */
    private RedisCacheService<String> redisTransCache;

    /**
     * 转换配置信息
     */
    private TransConfig transConfig;

    /**
     * 将
     *
     * @param customizer
     */
    public void registerDictionary(DictionaryTransCustomizer customizer) {
        dictionaryTransCustomizerMap.put(customizer.getDicTypeCode(), customizer);
        customizer.customizer(this);
    }

    @Override
    public void refreshCache(Map<String, Object> messageMap) {
        if (messageMap.keySet().contains("dicTypeCode")) {
            String dicTypeCode = (String) messageMap.get("dicTypeCode");
            if (!StringUtil.isEmpty(dicTypeCode)) {
                DictionaryTransCustomizer dictionaryTransCustomizer = dictionaryTransCustomizerMap.get(dicTypeCode);
                if (!ObjectUtils.isEmpty(dictionaryTransCustomizer)) {
                    LOGGER.debug("开始刷新字典:{}", dicTypeCode);
                    dictionaryTransCustomizer.customizer(this);
                    return;
                } else if ("ALL".equals(dicTypeCode)) {
                    LOGGER.debug("开始刷新所有字典");
                    dictionaryTransCustomizerMap.values().stream().forEach(c -> {
                        c.customizer(DictionaryTransService.this);
                        LOGGER.debug("字典 {} 刷新完成", c.getDicTypeCode());
                    });
                    return;
                }
                LOGGER.warn("未找到要刷新的字典");
            }
        }
    }

    /**
     * 刷新缓存
     *
     * @param dicTypeCode 字典类型编码
     * @param dicMap      字典map
     */
    @Override
    public void refreshCache(String dicTypeCode, Map<String, String> dicMap) {
        dicMap.keySet().forEach(key -> {
            put(dicTypeCode + "_" + key, dicMap.get(key));
        });

    }

    protected void put(String key, String value) {
        if (transConfig.isEnableRedis()) {
            this.getRedisTransCache().put(key, value);
        } else {
            dictionaryTransMap.put(key, value);
        }
    }
    protected String get(String key){
        if (transConfig.isEnableRedis()) {
         return this.getRedisTransCache().get(key);
        } else {
         return dictionaryTransMap.get(key);
        }
    }


    @Override
    public void transOne(VO obj, List<Field> toTransList) {
        Trans tempTrans = null;

        for (Field tempField : toTransList) {
            tempField.setAccessible(true);
            tempTrans = tempField.getAnnotation(Trans.class);
            String dicCodes = StringUtil.toString(ReflectUtils.getValue(obj, tempField.getName()));
            String[] dicCodeArray = dicCodes.split(",");
            String key = tempTrans.key().contains("KEY_") ? StringUtil.toString(ReflectUtils.getValue(obj, tempTrans.key().replace("KEY_", ""))) : tempTrans.key();
            //sex_0/1  男 女
            List<String> dicCodeList = new ArrayList<>();
            for (String dicCode : dicCodeArray) {
                if (!StringUtil.isEmpty(dicCode)) {
                    dicCodeList.add(get(key + "_" + dicCode));
                }
            }
            String transResult = dicCodeList.size() > Constant.ZERO ? StringUtil.getStrForIn(dicCodeList, false) : "";
            if (obj.getTransMap() != null) {
                obj.getTransMap().put(tempField.getName() + "Name", transResult);
            }
            setRef(tempTrans, obj, transResult);
        }
    }

    @Override
    public void transMore(List<? extends VO> objList, List<Field> toTransList) {
        for (VO obj : objList) {
            transOne(obj, toTransList);
        }
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        //注册自己为一个服务
        TransService.registerTransType(TransType.DICTIONARY, this);
        TransMessageListener.regTransRefresher(TransType.DICTIONARY, this::refreshCache);
    }

    public RedisCacheService<String> getRedisTransCache() {
        return redisTransCache;
    }

    public void setRedisTransCache(RedisCacheService<String> redisTransCache) {
        this.redisTransCache = redisTransCache;
    }

    public TransConfig getTransConfig() {
        return transConfig;
    }

    public void setTransConfig(TransConfig transConfig) {
        this.transConfig = transConfig;
    }
}
